package com.wollo.utils;

import org.csource.common.NameValuePair;
import org.csource.fastdfs.*;

import java.io.InputStream;
import java.util.Properties;

/**
 * FastDFS Java客户端工具
 */
public final class FastDFSUtils {
    /**
     * 定义静态属性，Properties和StorageClient
     */
    private final static Properties PROPERTIES;
    private final static StorageClient STORAGE_CLIENT;

    /**
     * 静态初始化代码块，初始化静态属性
     * 静态初始化代码块有异常如何处理？
     * 处理的时候，try。。catch。。 抛出一个Error，终止虚拟机。
     */
    static{
        try {
            PROPERTIES = new Properties();
            // 读取配置文件
            PROPERTIES.load(
                    FastDFSUtils.class
                            .getClassLoader()
                            .getResourceAsStream("fdfs.properties")
            );
            // 使用ClientGlobal初始化FastDFS客户端配置
            ClientGlobal.initByProperties(PROPERTIES);
            // 创建Tracker客户端对象
            TrackerClient trackerClient = new TrackerClient();
            // 基于Tracker客户端对象，获取Tracker服务器对象
            TrackerServer trackerServer = trackerClient.getConnection();
            // 基于Tracker服务器和客户端对象，获取Storage服务器对象
            StorageServer storageServer = trackerClient.getStoreStorage(trackerServer);
            // 创建Storage客户端对象
            STORAGE_CLIENT = new StorageClient(trackerServer, storageServer);
        }catch (Exception e){
            throw new ExceptionInInitializerError(e);
        }
    }

    /**
     * 删除文件
     * int delete_file(String 卷名, String 路径及文件名);
     * 返回值： 0代表成功，其他数字代表错误编码
     */
    public static int remote(String group, String remote){
        try {
            return STORAGE_CLIENT.delete_file(group, remote);
        }catch (Exception e){
            e.printStackTrace();
            return -1;
        }
    }

    /**
     * 查询某文件的元数据
     * @param group 卷名
     * @param remote 路径及文件名
     * @return 返回文件的元数据数组。发生错误返回null
     */
    public static NameValuePair[] getMetaData(String group, String remote){
        try{
            return STORAGE_CLIENT.get_metadata(group, remote);
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 下载文件工具方法
     *  下载方法
     *  byte[] download_file(String 卷名, String 路径及文件名)
     *  返回要下载的文件内容
     * @param group 卷名
     * @param remote 路径及文件名
     * @return 返回下载的文件内容，发生错误返回null
     */
    public static byte[] download(String group, String remote){
        try {
            return STORAGE_CLIENT.download_file(group, remote);
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 上传文件的工具方法
     * 一定保存文件到FastDFS，一定保存至少一个元数据（文件原始名称）
     * @param inputStream 要上传的文件的输入流
     * @param fileName 上传文件的原始名称
     * @param metaProperties 上传文件的元数据，成对提供，如： 名，值，名，值
     * @return
     */
    public static String[] uploadFile(InputStream inputStream, String fileName, String... metaProperties){
        try {
            int length = inputStream.available();
            byte[] datas = new byte[length];
            inputStream.read(datas, 0, length);
            // 处理元数据
            NameValuePair[] nameValuePairs = null;
            if (metaProperties.length % 2 == 0) {
                // 参数数量满足要求，开始处理
                nameValuePairs = new NameValuePair[metaProperties.length / 2 + 1];
                for (int i = 0; i < nameValuePairs.length; i = i + 2) {
                    nameValuePairs[i / 2] = new NameValuePair(metaProperties[i], metaProperties[i + 1]);
                }
            } else {
                nameValuePairs = new NameValuePair[1];
            }
            nameValuePairs[nameValuePairs.length - 1] = new NameValuePair("fileName", fileName);
            // 获取文件后缀
            String extName = getExtName(fileName);
            // 上传文件到FastDFS
            String[] result = STORAGE_CLIENT.upload_file(datas, extName, nameValuePairs);
            return result;
        }catch (Exception e){
            // 发生任何异常，上传文件失败。返回null
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 截取文件后缀
     * @param fileName
     * @return
     */
    private static String getExtName(String fileName){
        if(fileName.lastIndexOf(".") > -1){
            // 文件名称中包含字符 .
            return fileName.substring(fileName.lastIndexOf(".") + 1);
        }else{
            // 文件名称中不包含字符 .
            return "";
        }
    }

    /**
     * 提供获取Storage客户端对象的工具方法
     */
    public static StorageClient getStorageClient(){
        return STORAGE_CLIENT;
    }

    private FastDFSUtils(){}
}